from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from main.models import Excursion, Image, Excursion_Members, Outcrop, Outcrop_Collection
from userarea.forms import ImageForm, OutcropForm, ExcursionModelForm, OutcropModelForm, ExistingOutcropForm, JoinPrivateExcursion
from django.http import HttpResponseRedirect, HttpResponse
from rest_framework import status
from main.views import SearchBar
from util import linkImages

"""
View which loads the user's account page.
@precondition: must be authenicated.
"""
@login_required(login_url='/login/')
def index(request):
    searchForm = SearchBar()
    my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=request.user).values('excursion__pk')))
    height = 30
    if my_excursions.count() != 0:
        height = my_excursions.count() * 30
    return render_to_response('user/userHome.html', {'title':'Account Home','searchForm':searchForm, 'excursionForm': False, 'my_excursions':my_excursions, 'height':height } ,context_instance=RequestContext(request))

"""
View which loads the user's account page with the create excursion form or handles the creation of a new excursion.
@precondition: must be authenicated.
"""
@login_required(login_url='/login/')
def new_excursion(request):
    searchForm = SearchBar()
    form = ExcursionModelForm()
    if request.method == 'POST':
        form = ExcursionModelForm(request.POST)
        if form.is_valid():
            instance = form.save(False)
            instance.owner = request.user
            instance.save()
            #excursion owner as a member of the excursion
            member_instance = Excursion_Members(user=request.user, excursion=instance)
            member_instance.save()
            return HttpResponseRedirect('/user/excursion/'+str(instance.pk)+'/')
    my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=request.user).values('excursion__pk')))
    height = 30
    if my_excursions.count() != 0:
        height = my_excursions.count() * 30
    return render_to_response('user/userHome.html', {'title':'Create New Excursion', 'excursionForm': True , 
            'item_list':[form], 'my_excursions':my_excursions, 'searchForm':searchForm, 'height':height} ,context_instance=RequestContext(request))

"""
View which loads the excursion page. It will only load the page if the user is a member of that excursion.
@precondition: must be authenicated.
@precondition: must be a member of the excursion.
"""
@login_required(login_url='/login/')
def view_excursion(request, ex_id):
    excursion = Excursion.objects.get(pk=ex_id)
    searchForm = SearchBar()
    #check if the user is a member of the excursion
    if Excursion_Members.objects.filter(user=request.user, excursion=excursion).exists():
        if Excursion.objects.filter(pk=ex_id, owner=request.user).exists():
            isAdmin = True
        else:
            isAdmin = False
        images = Image.objects.filter(excursion=excursion)[:20]
        outcrop_list = Outcrop.objects.filter(pk__in=(Outcrop_Collection.objects.filter(excursion=excursion).values('outcrop__pk')))
        if outcrop_list is not None:
            hasOutcrops=True
        else:
            hasOutcrops=False
        return render_to_response('user/excursion.html', {'title':'Excursion', 'onLoad':'init()',
                'excursionItem':excursion, 'images':images, 'hasOutcrops':hasOutcrops, 'searchForm':searchForm, 'isAdmin':isAdmin,
                'outcrop_list':outcrop_list } ,context_instance=RequestContext(request))
    else:
        return HttpResponse('Unauthorized', status=status.HTTP_401_UNAUTHORIZED)

"""
View which loads the view images page. It will only load images for that excursion.
@precondition: must be authenicated.
"""
@login_required(login_url='/login/')
def excursion_view_images(request, ex_id, img_id, index):
    excursion = Excursion.objects.get(pk=ex_id);
    index = int(index)
    img_id = int(img_id)
    count = Image.objects.filter(excursion = excursion).count()
    searchForm = SearchBar()
    if img_id == 0:
        if index > count-1 and index < 0:
            index = 0   #loop around
        image = Image.objects.filter(excursion = excursion)[index]
    else:
        image =  Image.objects.get(pk = img_id, excursion=excursion)
        
    if index==0:
        pIndex = count-1    #loop around
    else:
        pIndex = index-1
    if index+1 > count-1:
        nIndex = 0
    else:
        nIndex = index+1
    
    current = index+1
    return render_to_response('user/viewImages.html', {'title':'Excursion Images', 'searchForm':searchForm, 'image':image,
        'pIndex':pIndex, 'nIndex':nIndex, 'count':count, 'current':current, 'currentIndex':index, 'fromExcursion':True, 'excursionItem':excursion } ,context_instance=RequestContext(request))

"""
View which loads the view images page. It will load all images for the outcrop.
@precondition: must be authenicated.
"""
def outcrop_view_images(request, out_id, img_id, index):
    outcrop = Outcrop.objects.get(pk=out_id);
    searchForm = SearchBar()
    index = int(index)
    img_id = int(img_id)
    count = Image.objects.filter(outcrop = outcrop, public=True).count()
    if img_id == 0:
        if index > count-1 and index < 0:
            index = 0   #loop around
        image = Image.objects.filter(outcrop = outcrop, public=True)[index]
    else:
        try:
            image =  Image.objects.get(pk = img_id, outcrop=outcrop, public=True)
        except Image.DoesNotExist:
            return HttpResponse('Unauthorized', status=status.HTTP_401_UNAUTHORIZED)

    if index==0:
        pIndex = count-1    #loop around
    else:
        pIndex = index-1
    if index+1 > count-1:
        nIndex = 0
    else:
        nIndex = index+1
    
    current = index+1
    return render_to_response('user/viewImages.html', {'title':'Excursion Images', 'searchForm':searchForm, 'image':image,
        'pIndex':pIndex, 'nIndex':nIndex, 'count':count, 'current':current, 'currentIndex':index, 'fromExcursion':False, 'outcrop':outcrop } ,context_instance=RequestContext(request))

"""
View to allow a user to create a new outcrop and link it to an excursion
@precondition: must be authenicated.
"""
@login_required(login_url='/login/')
def add_outcrop(request, ex_id):
    excursion = Excursion.objects.get(pk=ex_id)
    searchForm = SearchBar()
    user = request.user
    state = ""
    newForm = OutcropForm()
    existingForm = ExistingOutcropForm()
    mapError = ""
    #only allow excursion owner to create new outcrops
    if request.method == 'POST':
        #Determine if the user chose to create a new outcrop or using an existing outcrop
        newForm = OutcropModelForm(request.POST)
        if newForm.is_valid():
            instance = newForm.save(commit=False)
            instance.owner = request.user
            try:
                Outcrop.objects.get(name=instance.name)
                state = "An outcrop with this name already exists, please try a different name."
            except Outcrop.DoesNotExist:           
                instance.save()
                #make the new outcrop a member of the excursion
                collection_instance = Outcrop_Collection(excursion=excursion, outcrop=instance, public=excursion.public)
                collection_instance.save()
                linkImages(excursion)
                return HttpResponseRedirect('/user/excursion/edit/'+str(ex_id)+'/')
        else:
            mapError="You must specifiy a location on the map, click the map to do so."
    my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
    height = 30
    if my_excursions.count() != 0:
        height = my_excursions.count() * 30
    outcrop_list = Outcrop_Collection.objects.exclude(excursion=excursion)
    return render_to_response('user/createOutcrop.html', {'title':'Create New Outcrop', 'height':height, 'searchForm':searchForm, 'my_excursions':my_excursions, 'mapError':mapError, 'newForm':newForm, 'existingForm':existingForm,
                'excursionItem':excursion, 'state':state, 'outcrop_list':outcrop_list, 'onLoad':'init()' } ,context_instance=RequestContext(request))
"""
View to allow a user to link an existing outcrop to an excursion
@precondition: must be authenicated.
"""
@login_required(login_url='/login/')
def link_outcrop(request, ex_id):
    excursion = Excursion.objects.get(pk=ex_id)
    searchForm = SearchBar()
    user = request.user
    #only allow excursion owner to create new outcrops
    if request.method == 'POST':
        existingForm = ExistingOutcropForm(request.POST)
        if existingForm.is_valid():
            instance = Outcrop.objects.get(pk=existingForm.cleaned_data['key'])
            collection_instance = Outcrop_Collection(excursion=excursion, outcrop=instance, public=excursion.public)
            collection_instance.save()
            linkImages(excursion)
            return HttpResponseRedirect('/user/excursion/edit/'+str(ex_id)+'/')
        else:
            my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
            height = 30
            if my_excursions.count() != 0:
                height = my_excursions.count() * 30
            newForm = OutcropForm()
            outcrop_list = Outcrop_Collection.objects.exclude(excursion=excursion)
            return render_to_response('user/createOutcrop.html', {'title':'Create New Outcrop', 'height':height, 'searchForm':searchForm, 'my_excursions':my_excursions, 'newForm':newForm,
            'existingForm':existingForm, 'excursionItem':excursion, 'outcrop_list':outcrop_list, 'onLoad':'init()' },
            context_instance=RequestContext(request))
    else:
        my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
        height = 30
        if my_excursions.count() != 0:
            height = my_excursions.count() * 30
        newForm = OutcropForm()
        existingForm = ExistingOutcropForm()
        outcrop_list = Outcrop_Collection.objects.exclude(excursion=excursion)
        return render_to_response('user/createOutcrop.html', {'title':'Create New Outcrop', 'height':height, 'searchForm':searchForm, 'my_excursions':my_excursions, 'newForm':newForm,
            'existingForm':existingForm, 'excursionItem':excursion, 'outcrop_list':outcrop_list, 'onLoad':'init()' },
            context_instance=RequestContext(request))

"""
View to allow a user to edit an excursion
@precondition: must be authenicated.
@precondition: user must be the owner of the excursion.
"""
@login_required(login_url='/login/')
def edit_excursion(request, ex_id):
    searchForm = SearchBar()
    user = request.user
    if not Excursion.objects.filter(pk=ex_id).exists():
        return HttpResponse('Does not Exist', status=status.HTTP_400_BAD_REQUEST)
    if not Excursion.objects.filter(pk=ex_id, owner=request.user).exists():
        return HttpResponse('Unauthorized', status=status.HTTP_401_UNAUTHORIZED)
    
    excursion = Excursion.objects.get(pk=ex_id)
    form = ExcursionModelForm(instance=excursion)
    if request.method == 'POST':
        form = ExcursionModelForm(request.POST, instance=excursion)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/user/excursion/edit/'+str(ex_id)+'/')
    my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
    height = 30
    if my_excursions.count() != 0:
        height = my_excursions.count() * 30
    excursion = Excursion.objects.get(pk=ex_id)
    outcrop_list = Outcrop.objects.filter(pk__in=(Outcrop_Collection.objects.filter(excursion=excursion).values('outcrop__pk')))
    return render_to_response('user/editExcursion.html', {'title':'Editing Excursion',
        'searchForm':searchForm, 'height':height, 'my_excursions':my_excursions, 'excursionForm':form,
        'excursionItem':excursion, 'outcrop_list':outcrop_list, 'onLoad':'init()'}
        ,context_instance=RequestContext(request))
    
"""
View to allow a user to join a public excursion
@precondition: must be authenicated.
""" 
@login_required(login_url='/login/')
def join_excursion(request, ex_id):
    excursion = Excursion.objects.get(pk=ex_id)
    if Excursion_Members.objects.filter(user=request.user, excursion=excursion).exists():
        return HttpResponseRedirect('/user/excursion/'+str(ex_id)+'/')
    else:
        if excursion.public:
            member_instance = Excursion_Members(user=request.user, excursion=excursion)
            member_instance.save()
            return HttpResponseRedirect('/user/excursion/'+str(ex_id)+'/')
        else:
            return HttpResponseRedirect('/user/excursion/join/private/'+str(ex_id)+'/')

"""
View to allow a user to join a private excursion
@precondition: must be authenicated.
""" 
@login_required(login_url='/login/') 
def join_private_excursion(request, ex_id):
    excursion = Excursion.objects.get(pk=ex_id)
    user = request.user
    searchForm = SearchBar()
    if request.method == 'POST':
        form = JoinPrivateExcursion(request.POST)
        if form.is_valid():
            if form.cleaned_data['password']==excursion.password:
                member_instance = Excursion_Members(user=request.user, excursion=excursion)
                member_instance.save()
                return HttpResponseRedirect('/user/excursion/'+str(ex_id)+'/')
            else:
                my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
                form = JoinPrivateExcursion()
                height = 30
                if my_excursions.count() != 0:
                    height = my_excursions.count() * 30
                state="The password was incorrect."
                return render_to_response('user/userHome.html', {'title':'Join Excursion', 'excursionForm': False,
                    'joinForm':True, 'excursionItem':excursion, 'item_list':[form], 'my_excursions':my_excursions,
                    'height':height, 'state':state, 'searchForm':searchForm} ,context_instance=RequestContext(request))
        else:
            my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
            height = 30
            if my_excursions.count() != 0:
                height = my_excursions.count() * 30
            form = JoinPrivateExcursion()
            state="The password was incorrect."
            return render_to_response('user/userHome.html', {'title':'Create New Excursion', 'excursionForm': False,
                    'joinForm':True, 'excursionItem':excursion, 'item_list':[form], 'my_excursions':my_excursions,
                    'height':height, 'state':state, 'searchForm':searchForm} ,context_instance=RequestContext(request))
    else:
        my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
        height = 30
        if my_excursions.count() != 0:
            height = my_excursions.count() * 30
        form = JoinPrivateExcursion()
        return render_to_response('user/userHome.html', {'title':'Create New Excursion', 'excursionForm': False,
                    'joinForm':True, 'excursionItem':excursion, 'item_list':[form], 'my_excursions':my_excursions,
                    'height':height, 'searchForm':searchForm} ,context_instance=RequestContext(request))

"""
View to allow a user to view all of their images.
@precondition: must be authenicated.
""" 
@login_required(login_url='/login/')
def images(request):
    user = request.user
    excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
    images = Image.objects.filter(owner=user).select_related('excursion')
    my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=user).values('excursion__pk')))
    height = 30
    searchForm = SearchBar()
    if my_excursions.count() != 0:
        height = my_excursions.count() * 30
    return render_to_response('user/myImages.html', {'title':'My Images', 'my_excursions':my_excursions, 'height':height,
        'images':images, 'excursions':excursions,'searchForm':searchForm } ,context_instance=RequestContext(request))

"""
View to allow a user to edit an image
@precondition: must be authenicated.
@precondition: user must the owner of the image.
""" 
@login_required(login_url='/login/')
def edit_image(request, img_id):
    image = Image.objects.get(pk=img_id)
    height = 30
    searchForm = SearchBar()
    my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=request.user).values('excursion__pk')))
    outcrops = Outcrop.objects.filter(pk__in=(Outcrop_Collection.objects.filter(excursion=image.excursion).values('outcrop__pk')))
    form = ImageForm(instance=image)
    if my_excursions.count() != 0:
        height = my_excursions.count() * 30
    if (image.owner != request.user):
        return HttpResponse('Unauthorized', status=status.HTTP_401_UNAUTHORIZED)
    elif (request.method == 'POST'):
        form = ImageForm(request.POST, instance=image);
        
        if request.POST['outcrop'] == -1:
            outcrop = None
        else:
            try:
                outcrop = Outcrop.objects.get(pk = request.POST['outcrop'])
            except Outcrop.DoesNotExist:
                outcrop = None
        
        if form.is_valid():
            instance = form.save(False)
            instance.outcrop = outcrop
            instance.save()
            return HttpResponseRedirect('/user/images/edit/'+str(img_id)+'/')
    return render_to_response('user/editImage.html', {'title':'Edit Image', 'outcrops':outcrops, 'my_excursions':my_excursions, 'height':height, 
                'searchForm':searchForm, 'image':image, 'form':form} ,context_instance=RequestContext(request))

"""
View to allow a user to edit an outcrop
@precondition: must be authenicated.
@precondition: user must the owner of the outcrop.
""" 
@login_required(login_url='/login/')
def edit_outcrop(request, out_id):
    outcrop = Outcrop.objects.get(pk=out_id);
    my_excursions = Excursion.objects.filter(pk__in=(Excursion_Members.objects.filter(user=request.user).values('excursion__pk')))
    height = 30
    searchForm = SearchBar()
    if my_excursions.count() != 0:
        height = my_excursions.count() * 30
        
    if (outcrop.owner != request.user):
        return HttpResponse('Unauthorized', status=status.HTTP_401_UNAUTHORIZED)
    elif (request.method == 'POST'):
        form = OutcropModelForm(request.POST, instance=outcrop);
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/user/outcrop/edit/'+str(out_id)+'/')
        else:
            return render_to_response('user/editOutcrop.html', {'title':'My Images', 'my_excursions':my_excursions, 'height':height, 
                'searchForm':searchForm, 'form':form, 'outcrop':outcrop, 'onLoad':'init()'} ,context_instance=RequestContext(request))
    else:
        form = OutcropModelForm(instance=outcrop)
        return render_to_response('user/editOutcrop.html', {'title':'My Images', 'my_excursions':my_excursions, 'height':height, 
                'searchForm':searchForm, 'form':form, 'outcrop':outcrop, 'onLoad':'init()' } ,context_instance=RequestContext(request))
    
